fix(l1): use 0x80 sentinel for missing eth/71 BAL per EIP-8159#6744
Conversation
The eth/71 BlockAccessLists handler emitted 0xc0 (RLP empty list) for missing entries, but EIP-8159 §"BlockAccessLists (0x13)" mandates the RLP empty string 0x80: an empty list is a valid BAL encoding (block with no state changes), so only the empty string can never alias a real BAL. Affects both encode and decode of OptionalBal. geth uses rlp.EmptyString at eth/protocols/eth/handlers.go:693; the 0xc0 value would have caused silent data confusion on interop (geth decoding our missing slots as valid empty BALs). Adds a byte-exact test asserting 0x80 is present and 0xc0 is absent in a single-None response payload.
|
🤖 Kimi Code ReviewThis PR fixes an interoperability-critical encoding bug in EIP-8159 Block Access Lists (BAL) handling. The change is correct and well-tested. SummaryIssue: The previous implementation used RLP empty list ( Fix: Correctly uses Detailed Review
|
🤖 Claude Code ReviewCode Review: PR #6744 — Fix eth/71
|
Lines of code reportTotal lines added: Detailed view |
Greptile SummaryFixes the
Confidence Score: 5/5Safe to merge — a single, surgical byte-constant change with matching encode/decode symmetry and a new wire-level regression test. The change is minimal: two byte literals flipped from 0xc0 to 0x80 with a matching decode guard. The fix aligns with both the EIP-8159 spec and geth's reference implementation. All pre-existing roundtrip tests continue to pass because both sides of the codec were updated together. The new test independently checks the decompressed wire bytes, ensuring the sentinel cannot silently regress. No files require special attention.
|
| Filename | Overview |
|---|---|
| crates/networking/p2p/rlpx/eth/block_access_lists.rs | Sentinel byte corrected from 0xc0 to 0x80 in both encode and decode paths for OptionalBal; doc comment updated with EIP-8159 rationale; new regression test locks the wire format. |
Sequence Diagram
sequenceDiagram
participant ethrex as ethrex (eth/71)
participant wire as Wire (RLP)
participant geth as go-ethereum (eth/71)
Note over ethrex,geth: BlockAccessLists (0x13) response — missing BAL slot
ethrex->>wire: OptionalBal(None) → encode 0x80 (RLP empty string, EIP-8159)
wire->>geth: byte 0x80
geth->>geth: "rlp.EmptyString check passes → slot = unavailable ✓"
Note over ethrex,geth: Before fix (wrong sentinel 0xc0)
ethrex-->>wire: OptionalBal(None) → encode 0xc0 (RLP empty list)
wire-->>geth: byte 0xc0
geth-->>geth: "decode as zero-element list → slot = valid empty BAL ✗ (silent confusion)"
Reviews (1): Last reviewed commit: "fix(l1): use 0x80 sentinel for missing e..." | Re-trigger Greptile
🤖 Codex Code Review
The wire-format fix itself looks correct and aligns with the spec; the concerns above are about backward compatibility and test precision. I could not run Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
Summary
eth/71
BlockAccessLists(0x13) returns the wrong sentinel byte for missing BALs. EIP-8159 §"BlockAccessLists (0x13)" mandates the RLP empty string (`0x80`); our implementation emitted the RLP empty list (`0xc0`).`0xc0` is a valid encoding for an empty `BlockAccessList` (a block with no state changes), so using it as the "unavailable" sentinel makes "missing BAL" indistinguishable from "valid empty BAL" on the wire. The spec uses `0x80` because it can never alias a real BAL.
Why this matters
go-ethereum's eth/71 handler uses `rlp.EmptyString` (= `0x80`) at `eth/protocols/eth/handlers.go:693`, with the comment:
With ethrex on `0xc0` and geth on `0x80`:
Found while cross-checking the snap/2 (EIP-8189) PR against go-ethereum.
Changes
Test plan